<?php
namespace Modules\Payment\Entities;

use Yansongda\Pay\Pay;
use Modules\Payment\Entities\PaymentRecord;

use ThrowException;
use Miniapp;
use Cache;

class WechatPay
{
	protected $clientName;
	protected $payType;
	protected $pay;

	public function __construct($clientName, $payType)
	{
		$config = config('pay.wechat')['default'];

		// if ($clientName)
		// 	$key = $clientName . '_' . $payType;
		// else 
		// 	$key = array_keys($config)[0];

		// $config = $config[];

		$this->pay = Pay::wechat($config);
		$this->payType = $payType;
		$this->clientName = $clientName;
	}

	public function __call($name, $arguments)
    {
    	return call_user_func_array(array($this->pay, $name), $arguments);
    }

	public function config($user, $order)
	{
		$money = $order->payPrice();
		$title = $order->title();
		$number = $order->payNumber();

		// 截取限定长度标题  
		$title = mb_substr($title, 0, 30);

        // for test
        // $money = 1;

		$wechatPayOrder = [
			'out_trade_no' => $number,
			'body' => $title,
			'total_fee' => $money,
		];

		// $wechatPayOrder = [
		//     'out_trade_no' => time(),
		//     'description' => 'subject-测试',
		//     'amount' => [
		//         'total' => '1',
		//     ],
		// ];

		try {
			switch ($this->payType) {
	            case 'miniapp':
	                $wechatPayOrder['openid'] = $user->getOpenid('miniapp', $this->clientName);

	                $config = $this->pay->miniapp($wechatPayOrder);
	                break;

	            case 'h5': 
	            	// 普通h5 (非微信中打开)
	            	$config = $this->pay->wap($wechatPayOrder);
	            	$url = $config->getTargetUrl();

	            	if (!$url) {
	            		ThrowException::Conflict('h5配置支付失败~');
	            	}

	            	$config = [
	            		'url' => $url
	            	];
	            	break;

	            case 'wechat_h5':
	            	// 公众号支付
	            	$openId = $user->getOpenid('web', $this->clientName);
	            	if (!$openId) {
	            		ThrowException::Conflict('请先微信授权才可支付~');
	            	}
	            	$wechatPayOrder['openid'] = $openId;
	                $config = $this->pay->mp($wechatPayOrder);
	                break;

	            case 'wechat_qrcode':
	                break;

	            case 'app': 
	                $config = json_decode($this->pay->app($wechatPayOrder)->getContent());
	                break;

	            default:
	                break;
	        }
        }
		catch(\Yansongda\Pay\Exceptions\GatewayException $e) {
			$err  = $e->getMessage();
			\Log::error('获取微信支付配置失败: ' . $err);
			
			ThrowException::Conflict($err);
		}

		// 记录prepay_id
		if ($this->payType === 'miniapp' && isset($config['package'])) {
			$prepayId = @explode('=', $config['package'])[1];

			if ($this->payType === 'miniapp') {
				Cache::put('prepay_id_' . $order->id, $prepayId, '300');
			}
		}

        return $config;
	}

	public function refundMoney($order, $refundMoney = null, $options = []) 
	{
		// $payment = $order->payment() ?: ThrowException::Conflict('订单无支付记录');

		// \Log::error($payment);
		// exit();

		$orderType = 'single_order';

		$remark = @v($options['remark'], '订单退款');

		// $paymentRecord = $order->payment();
		$number = $order->pay_number;

		// \Log::error($number);
		// exit();

		$info = [
			'out_trade_no' => $number,
			'out_refund_no' => time(),
			'total_fee' => $order->pay_money_price,
			'refund_fee' => $refundMoney,
			'refund_desc' => $remark,
		];

		try {
			$res = $this->pay->refund($info);
		}
		catch(\Yansongda\Pay\Exceptions\GatewayException $e) {
			$err = $e->getMessage();
			\Log::error('订单: ' . $order->id . ' 退款失败:' . $err);
			ThrowException::Conflict('退款失败:' .  $err);
		}
	}


	public function recordPayment($order, $clientName, $paySubType, $data, $options = [])
	{
		$info = [
			'trade_number' => $data->transaction_id,
			'out_trade_number' => $data->out_trade_no,
			'client_name' => $clientName,
			'pay_type' => 'wechat',
			'pay_sub_type' => $paySubType,
			'paid_at' => $data->time_end,
			'money' => $data->total_fee,
			'status' => 2,
			'options' => $data
		];

		if ($order->number[0] == 'U') 
			$info['union_order_id'] = $order->id;
		else
			$info['order_id'] = $order->id;

		$record = PaymentRecord::create($info);

		$record->save();
	}
}
